<template>
    <el-form ref="DynamicForm" :model="formData" v-bind="formProps" @validate="handleValidateEvent">
        <template v-for="(item, index) in formItems">
            <el-form-item :key="index" :ref="item.prop" v-if="filterFormItem(item)"
                          v-bind="getFormItemProps(item)">
                <Widget v-model="formData[item.prop]" v-bind="getWidgetProps(item)"
                        :event="item.widget.event" :slots="item.widget.slots" />
            </el-form-item>
        </template>
    </el-form>
</template>

<script>
import {ElForm, ElFormItem, genProps, widgetDefaultProps} from "./attributes";

export default {
    name: "Dynamic",
    components: {
        Widget: () => import('./Widget'),
    },
    props: {
        formConfig: {
            type: Object,
            default: null,
        },
        formEvent: {
            type: Object,
            default: null,
        },
        data: {
            type: Object,
            default: null,
        },
        disabled: {
            type: Boolean,
            default: null,
        },
    },
    data() {
        return {
            formData: {},
            widgetDefaultProps: {
                ...widgetDefaultProps,
            },
        };
    },
    computed: {
        formProps() {
            let props = genProps(ElForm, this.formConfig)
            if (this.disabled) {
                props.disabled = this.disabled;
            }
            return props;
        },
        formItems() {
            let items = [];
            if (this.formConfig && this.$utils.isNotEmptyList(this.formConfig.items)) {
                items = this.formConfig.items.map(item => {
                    let obj = $.extend({}, item);
                    if (!item.widget) {
                        obj.widget = {
                            name: 'ElInput',
                        };
                    }
                    return obj;
                });
            }
            return items;
        },
    },
    watch: {
        data: {
            handler() {
                if (this.data) {
                    this.formData = $.extend({}, this.data);
                }
            },
            deep: true,
            immediate: true,
        },
    },
    methods: {
        filterFormItem(item) {
            if (typeof item.filter === 'function') {
                return item.filter(item, this.formData);
            }
            return true;
        },
        getFormItemProps(item) {
            let props = genProps(ElFormItem, item);
            if (item.style) {
                props.style = item.style;
            }
            return props;
        },
        getWidgetProps(item) {
            let widgetProps = genProps(this.widgetDefaultProps, item.widget);
            if (item.widget.props) {
                let attributes = widgetProps.attributes || {};
                widgetProps.attributes = $.extend({}, attributes, item.widget.props);
            }
            return widgetProps;
        },
        handleValidateEvent(e) {
            this.formEvent && typeof this.formEvent.validate === 'function' && this.formEvent.validate(e);
        },
        validate(callback) {
            if (this.$refs.DynamicForm) {
                this.$refs.DynamicForm.validate(callback);
            }
        },
        async validateDynamicForm() {
            return await this.validateForm('DynamicForm');
        },
        validateField(props, callback) {
            if (this.$refs.DynamicForm) {
                this.$refs.DynamicForm.validateField(props, callback);
            }
        },
        resetFields() {
            if (this.$refs.DynamicForm) {
                this.$refs.DynamicForm.resetFields();
            }
        },
        clearValidate(props) {
            if (this.$refs.DynamicForm) {
                this.$refs.DynamicForm.clearValidate(props);
            }
        },
        resetField(prop) {
            if (this.$refs[prop]) {
                this.$refs[prop].resetField();
            }
        },
        clearFieldValidate(prop) {
            if (this.$refs[prop]) {
                this.$refs[prop].clearValidate();
            }
        },
    },
}
</script>

<style scoped lang="less">

</style>
